﻿using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Server.Features;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Prometheus;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.NetworkInformation;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Helpers
{
    public static class PrometheusHelperExtensions
    {
        private static MetricPusher _metricPusher;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="services"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        public static IServiceCollection AddPrometheusHelperz(this IServiceCollection services, PrometheusHelperOptions options)
        {
            services.AddSingleton<PrometheusHelperOptions>(_ => options);
            services.AddSingleton<IStartupFilter, PrometheusHelperStartupFilter>();
            return services;
        }

        /// <summary>
        /// 开启MetricPusher,自动添加ip:port标签
        /// </summary>
        [Obsolete("使用AddPrometheusHelperz")]
        public static async Task<IApplicationBuilder> UsePrometheusHelperz(this IApplicationBuilder app, PrometheusHelperOptions options)
        {
            try
            {
                if (options.IsStartMetricPusher)
                {
                    if (options.MetricPusherOptions == null) throw new ArgumentNullException(nameof(options.MetricPusherOptions));
                    options.MetricPusherOptions.Job ??= AppDomain.CurrentDomain.FriendlyName;
                    if (_metricPusher == null)
                    {
                        //var features = app.Properties["server.Features"] as FeatureCollection;
                        var features = app.ServerFeatures;
                        var port = Regex.Match(features.Get<IServerAddressesFeature>()
                            .Addresses
                            .FirstOrDefault() ?? "", @":(\d+)").Groups[1].Value;

                        string ip = null;
                        try
                        {
                            var env = app.ApplicationServices.GetService<IWebHostEnvironment>();
                            if (env != null && !env.IsDevelopment())
                            {
                                //ip = (await IpHelper.GetRemoteIp().ConfigureAwait(false)).Ip;
                                using var client = new HttpClient();
                                client.Timeout = TimeSpan.FromSeconds(5);
                                var firstIpV4Address = await client.GetStringAsync(options.IpParserUrl).ConfigureAwait(false);
                            }
                        }
                        catch (Exception)
                        {
                        }
                        if (string.IsNullOrWhiteSpace(ip))
                        {
                            //NetworkInterface[] adapters = NetworkInterface.GetAllNetworkInterfaces(); //适配器
                            ip = IpHelper.GetLocalIp().Ip;
                        }

                        var address = $"{ip}:{port}";

                        if (string.IsNullOrWhiteSpace(options.MetricPusherOptions.Instance))
                        {
                            options.MetricPusherOptions.Instance = address;
                        }
                        else
                        {
                            List<Tuple<string, string>> list = options.MetricPusherOptions.AdditionalLabels == null ? new List<Tuple<string, string>>() : new List<Tuple<string, string>>(options.MetricPusherOptions.AdditionalLabels);
                            if (!options.MetricPusherOptions.AdditionalLabels.Any(x => x.Item1 == "ip"))
                            {
                                list.Add(new Tuple<string, string>("ip", address));
                            }
                            options.MetricPusherOptions.AdditionalLabels = list;
                        }
                        _metricPusher = new MetricPusher(options.MetricPusherOptions);
                        _metricPusher.Start();
                        Console.WriteLine($"start MetricPusher {address}");
                    }
                }
                if (options.IsUseHttpMetrics)
                {
                    app.UseHttpMetrics();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("UseMetricPusherHelper异常--" + ex.ToString());
            }
            return app;
        }
    }
}
